﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Entities;
using System.Collections;

namespace Utilites
{
    /// <summary>
    /// Smart BaseEntity Dictionary
    /// Load-on-Index-Access
    /// </summary>
    public class SmartDictionary : IEnumerable<BaseEntity>
    {
        private Dictionary<int, BaseEntity> _dict = new Dictionary<int, BaseEntity>();

        /// <summary>
        /// Делегат метода загрузки значений
        /// </summary>
        /// <param name="key">ID загружаемого объекта</param>
        /// <returns></returns>
        public delegate BaseEntity LoadMethodDelegate(int ID);

        public IEnumerable<BaseEntity> Values
        {
            get
            {
                return _dict.Values;
            }
        }

        private LoadMethodDelegate _load_func;

        /// <summary>
        /// Базовый конструктор. Создает пустой словарь
        /// </summary>
        /// <param name="ValueLoadMethod">Метод загрузки объектов</param>
        public SmartDictionary(LoadMethodDelegate ValueLoadMethod)
        {
            if (ValueLoadMethod == null)
            {
                throw new ArgumentNullException();
            }
            _load_func = ValueLoadMethod;
        }

        /// <summary>
        /// Конструктор. Создает словарь по имеющемуся перечислению объектов BaseEntity
        /// </summary>
        /// <param name="ValueLoadMethod"></param>
        /// <param name="source_collection"></param>
        public SmartDictionary(LoadMethodDelegate ValueLoadMethod, IEnumerable<BaseEntity> source_collection)
        {
            if (ValueLoadMethod == null || source_collection == null)
            {
                throw new ArgumentNullException();
            }
            _load_func = ValueLoadMethod;
            foreach (var item in source_collection)
            {
                this[item.ID] = item;
            }
        }

        public BaseEntity this[int key]
        {
            get
            {
                if (_dict.ContainsKey(key))
                {
                    return _dict[key];
                }
                else
                {
                    _dict.Add(key, _load_func(key));
                    return _dict[key];
                }
            }
            set
            {
                if (_dict.ContainsKey(key))
                {
                    _dict[key] = value;
                }
                else
                {
                    _dict.Add(key, value);
                }
            }
        }

        /// <summary>
        /// Метод удаления объектов из словаря
        /// </summary>
        /// <param name="id">ID удаляемого объекта</param>
        public void RemoveObject(int id)
        {
            _dict.Remove(id);
        }

        IEnumerator<BaseEntity> IEnumerable<BaseEntity>.GetEnumerator()
        {
            return _dict.Values.GetEnumerator();
        }
    }
}
